#pragma once

#include <iostream>
#include <string>
#include <pthread.h>
#include <functional>
#include <sys/types.h>
#include <unistd.h>

using func_t = std::function<void()>;
static int number = 1;
enum class TSTATUS
{
    NEW,
    RUNNING,
    STOP
};

class Thread
{
private:
    // 成员方法！
    static void *Routine(void *args)
    {
        Thread *t = static_cast<Thread *>(args);
        t->_status = TSTATUS::RUNNING;
        t->_func();
        return nullptr;
    }
    void EnableDetach() { _joinable = false; }
    bool IsJoinable() { return _joinable; }
public:
    Thread(func_t func) : _func(func), _status(TSTATUS::NEW), _joinable(true)
    {
        _name = "Thread-" + std::to_string(number++);
        _pid = getpid();
    }
    bool Start()
    {
        if (_status != TSTATUS::RUNNING)
        {
            int n = ::pthread_create(&_tid, nullptr, Routine, this); 
            if (n != 0)
                return false;
            return true;
        }
        return false;
    }
    bool Stop()
    {
        if (_status == TSTATUS::RUNNING)
        {
            int n = ::pthread_cancel(_tid);
            if (n != 0)
                return false;
            _status = TSTATUS::STOP;
            return true;
        }
        return false;
    }
    bool Join()
    {
        if (_joinable)
        {
            int n = ::pthread_join(_tid, nullptr);
            if (n != 0)
                return false;
            _status = TSTATUS::STOP;
            return true;
        }
        return false;
    }
    void Detach()
    {
        EnableDetach();
        pthread_detach(_tid);
    }
    std::string Name()
    {
        return _name;
    }
    pid_t tid()
    {
        return _tid;
    }
    ~Thread()
    {
    }
private:
    std::string _name;
    pthread_t _tid;
    pid_t _pid;
    bool _joinable; // 是否是分离的，默认不是
    func_t _func;
    TSTATUS _status;
};